/*
 * author: ovsexia
 * version: 2.3.1
 * name: Jq Driver
 * describe: jq网站常用方法与模板渲染
 * License: Mozilla Public License Version 2.0
 */

;(function($){
  $.fn.jqdriver = function(options){
    const defaults = {
      active: 'on',  //活动css类名
    };
    options = $.extend(defaults, options);

    //方法
    let methods = new Object();

    //网页宽高
    methods.xwidth = window.innerWidth;
    methods.xheight = window.innerHeight;

    //客户端
    //苹果端
    if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
      methods.ios = true;
    }else{
      methods.ios = false;
    }
    //安卓端
    if(/(Android)/i.test(navigator.userAgent)){
      methods.android = true;
    }else{
      methods.android = false;
    }
    //手机端
    if(methods.ios || methods.android){
      methods.app = true;
    }else{
      methods.app = false;
    }
    //微信端
    if(/(MicroMessenger)/i.test(navigator.userAgent)){
      methods.wechat = true;
    }else{
      methods.wechat = false;
    }
    //微信小程序端
    if(/(miniProgram)/i.test(navigator.userAgent)){
      methods.wechatPro = true;
    }else{
      methods.wechatPro = false;
    }
    //微信端，且非小程序端
    if(methods.wechat === true && methods.wechatPro === false){
      methods.wechatNoPro = true;
    }else{
      methods.wechatNoPro = false;
    };

    /* 网页滚动至元素
     * ele    元素
     * poi    上下偏移值，正数偏上，负数偏下
     * speed  动画速度
     */
    methods.slideto = function(ele, poi, speed){
      if(typeof(speed) == 'undefined'){
        speed = 500;
      }
      let toppix;
      if(ele == 'bodyBottom'){
        toppix = $(document).height();
      }else{
        if($(ele).length === 0){
          console.log('%c Element does not exist!', 'color:red');
          return false;
        }
        toppix = $(ele).offset().top;
      }
      if(poi){
        toppix = Number(toppix) + Number(poi);
        if(ele == 'bodyBottom'){
          toppix -= methods.xheight;
        }
      }
      $('html, body').animate({scrollTop:(toppix + 'px')}, speed);
    };

    /* 打开链接
     * url     链接
     * target  打开方式[blank(新窗口)]
     */
    methods.open = function(url, target){
      if(url){
        if(target == 'blank' || target == '_blank'){
          window.open(url);
        }else{
          window.location.href = url;
        }
      }
    };

    methods.cssTurn = function(type, ele, para){
      para = para || {};
      if(!para.cssname){
        para.cssname = options.active;
      }
      if(type == 'on'){
        if($(ele).hasClass(para.cssname)){
          return false;
        }
        $(ele).addClass(para.cssname);
      }else if(type == 'off'){
        if(!$(ele).hasClass(para.cssname)){
          return false;
        }
        $(ele).removeClass(para.cssname);
      }else if(type == 'switch'){
        $(ele).toggleClass(para.cssname);
      }

      if(para.blank){
        let tagarr = ['INPUT', 'TEXTAREA', 'BUTTON', 'SELECT', 'A'];
        $(document).click(function(e){
          let children = $(para.blank).children();
          if(children.length > 0){
            for(let i=0; i<children.length; i++){
              if(e.target == children[i]){
                return false;
              }
            }
          }
          if(e.target != para.blank){
            //子元素排除
            let sontarget = function(target){
              let parents = $(target).parents();
              for(let i=0; i<parents.length; i++){
                if($(parents[i])[0].tagName != 'BODY' && $(parents[i])[0].tagName != 'HTML'){
                  if($(parents[i])[0] == para.blank){
                    return true;
                  }
                }
              }
              return false;
            }(e.target);

            if(tagarr.indexOf(e.target.tagName) == -1 && sontarget == false){
              if(type == 'on'){
                if(!$(ele).hasClass(para.cssname)){
                  return false;
                }
                $(ele).removeClass(para.cssname);
              }else if(type == 'off'){
                if($(ele).hasClass(para.cssname)){
                  return false;
                }
                $(ele).addClass(para.cssname);
              }else if(type == 'switch'){
                $(ele).removeClass(para.cssname);
              }
            }
          }
        });
      }
    };

    /* 添加活动CSS
     * ele      元素
     * cssname  css类名
     */
    methods.cssOn = function(ele, para){
      return this.cssTurn('on', ele, para);
    };

    /* 删除活动CSS
     * ele      元素
     * cssname  css类名
     */
    methods.cssOff = function(ele, para){
      return this.cssTurn('off', ele, para);
    };

    /* 添加或删除活动CSS
     * ele      元素
     * cssname  css类名
     */
    methods.cssSwitch = function(ele, para){
      return this.cssTurn('switch', ele, para);
    };

    /* 获取下拉框选中值
     * ele   元素
     * type  类型[index(索引值) | value(value值) | html(内容)]
     */
    methods.select = function(ele, type){
      if(!type){
        type = 'index';
      }
      let result;
      if(type == 'index'){
        result = $('#'+ele).find('option:selected').index();
      }else if(type == 'value'){
        result = $('#'+ele).find('option:selected').val();
      }else if(type == 'html'){
        result = $('#'+ele).find('option:selected').html();
      }
      return result;
    };

    //只能输入数字
    methods.onlyNum = function(ele){
      let str = $(ele).val();
      let num = str.match(/-?([0-9]\d*(\.\d*)*|0\.[0-9]\d*)/g);
      $(ele).val(num);
    };

    /* 表单验证
     * ele      表单元素
     * error    弹层消息方法，可填入第三方暴露的全局对象
     * success  第三方弹层方法的参数对象
     */
    methods.subCheck = function(ele, error, success){
      let input = $(ele).find('[jdForm]');
      if(input.length > 0){
        for(let i=0; i<input.length; i++){
          let that = $(input[i]);
          let intype = that.attr('type');
          let ftype = that.attr('jdForm');
          let ftypearr = ftype.split('||');
          let msg = that.attr('jdMsg');
          let msgarr, msgall;
          if(msg){
            msgarr = msg.split('||');
          }

          for(let y=0; y<ftypearr.length; y++){
            if(ftypearr[y] == 'required'){  //必填
              if(intype=='checkbox'){
                if(that.prop('checked')===false){
                  msgall = (msgarr && msgarr[y]) ? msgarr[y] : '项目未选中';
                  if(error && typeof(error)=='function'){
                    error(msgall);
                  }else{
                    alert(msgall);
                  }
                  that.focus();
                  return false;
                }
              }else{
                if(!that.val()){
                  msgall = (msgarr && msgarr[y]) ? msgarr[y] : '数值不能为空';
                  if(error && typeof(error)=='function'){
                    error(msgall);
                  }else{
                    alert(msgall);
                  }
                  that.focus();
                  return false;
                }
              }
            }else if(ftypearr[y] == 'email' || ftypearr[y] == 'number' || ftypearr[y] == 'int'){  //格式验证
              if(that.val()){
                let value = that.val();
                let reg;
                if(ftypearr[y] == 'email'){  //邮箱
                  reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
                  msgall = (msgarr && msgarr[y]) ? msgarr[y] : '邮箱格式错误';
                }else if(ftypearr[y] == 'number'){  //数字
                  reg = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/;
                  msgall = (msgarr && msgarr[y]) ? msgarr[y] : '格式错误';
                }else if(ftypearr[y] == 'int'){  //整数
                  reg = /^\d+$/;
                  msgall = (msgarr && msgarr[y]) ? msgarr[y] : '格式错误';
                }

                if(!reg.test(value)){
                  if(error && typeof(error)=='function'){
                    error(msgall);
                  }else{
                    alert(msgall);
                  }
                  that.focus();
                  return false;
                }
              }
            }else if(ftypearr[y] == 'pass1' || ftypearr[y] == 'pass2' || ftypearr[y] == 'pass3' || ftypearr[y] == 'pass4'){  //密码强度
              msgall = (msgarr && msgarr[y]) ? msgarr[y] : '密码强度不够';
              if(that.val()){
                let value = that.val();
                let reg;
                if(ftypearr[y] == 'pass1'){
                  reg = /\w{6}/;
                }else if(ftypearr[y] == 'pass2'){
                  reg = /^.*(?=.{6,})(?=.*\d)(?=.*[a-z]).*$/;
                }else if(ftypearr[y] == 'pass3'){
                  reg = /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z]).*$/;
                }else if(ftypearr[y] == 'pass4'){
                  reg = /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*?()+-]).*$/;
                }

                if(!reg.test(value)){
                  if(error && typeof(error)=='function'){
                    error(msgall);
                  }else{
                    alert(msgall);
                  }
                  that.focus();
                  return false;
                }
              }else{
                if(error && typeof(error)=='function'){
                  error(msgall);
                }else{
                  alert(msgall);
                }
                that.focus();
                return false;
              }
            }else if(ftypearr[y] == 'mobile'){  //11位手机号码
              msgall = (msgarr && msgarr[y]) ? msgarr[y] : '手机号码格式错误';
              if(that.val()){
                let value = that.val();
                let reg = /^1[3458]{1}\d{9}$/;  //13 14 15 18开头

                if(!reg.test(value)){
                  if(error && typeof(error)=='function'){
                    error(msgall);
                  }else{
                    alert(msgall);
                  }
                  that.focus();
                  return false;
                }
              }
            }
          }
        };
      }
      if(success && typeof(success)=='function'){
        success();
      }
      return true;
    };

    //计算实际尺寸
    methods.realSize = function(type, size, ele){
      size = size.trim();
      let pre = size.slice(0, 1);
      let last = size.slice(-1);
      let newsize = 0;

      if(type == 'width' || type == 'height'){
        let reg, xsize;
        reg = /^[@|#][\d.]+\%[\s]*[+|-][\s]*[\d.]+(px)$/;  //@50%-20px #50%-20px
        let pre = size.slice(0, 1);
        if(pre == '@'){  //根据网页
          if(type == 'width'){
            xsize = this.xwidth;
          }else if(type == 'height'){
            xsize = this.xheight;
          }
        }else if(pre == '#'){  //根据父元素
          if(type == 'width'){
            xsize = $(ele).parent().width();
          }else if(type == 'height'){
            xsize = $(ele).parent().height();
          }
        }

        if(reg.test(size)){
          let size_1 = size.match(/^[@|#][\d.]+\%/g);
          let size_2 = size.match(/[\d.]+(px)$/g);
          let size_a = Number(size_1[0].slice(1, -1));
          let size_b = Number(size_2[0].slice(0, -2));
          let size_type = size.match(/[+|-]/g);
          if(size_type == '+'){
            newsize = ((xsize * size_a * 0.01) + size_b).toFixed(2);
          }else if(size_type == '-'){
            newsize = ((xsize * size_a * 0.01) - size_b).toFixed(2);
          }
          return newsize;
        }

        reg = /^[@|#][\d.]+\%$/;  //@50% #50%
        if(reg.test(size)){
          let size_1 = size.match(/^[@|#][\d.]+\%/g);
          let size_a = Number(size_1[0].slice(1, -1));
          newsize = (xsize * size_a * 0.01).toFixed(2);
          return newsize;
        }

        newsize = size;
        return newsize;
      }else{
        newsize = size;
        return newsize;
      }
    };

    //css字符串转对象
    methods.cssObj = function(cssstr, ele){
      let last = cssstr.slice(-1);
      if(last == ';'){
        cssstr = cssstr.slice(0, -1);
      }
      let cssarr = cssstr.split(';');
      let obj = new Object();
      let arr;
      for(let i=0; i<cssarr.length; i++){
        arr = cssarr[i].split(':');
        obj[arr[0].trim()] = this.realSize(arr[0].trim(), arr[1], ele);
      }
      return obj;
    };


    //模板渲染
    methods.render = function(list, parent, son, position){
      let that = this;
      if($(list).length > 0 && $(parent).length > 0 && $(son).length > 0){
        if(!position){
          position = 'append';
        }
        let temp = $(son).get(0);
        let tempHtml = $(temp).prop('outerHTML');
        let newdiv, list_i, tempParent, li;
        tempParent = $('<div class="jd_temp"></div>').appendTo('body').hide();
        for(let i=0; i<list.length; i++){
          newdiv = $(tempHtml).appendTo(tempParent);
          newdiv.attr('id', null);
          list_i = list[i];

          //本身绑定
          if(newdiv.attr('jdBind')){
            methods.renderBind(newdiv, list_i);
          }

          //查找子元素绑定
          li = newdiv.find('[jdBind]');
          li.each(function(){
            that.renderBind(this, list_i);
          });
        }
        if(position == 'append'){
          $(parent).append($(tempParent).children());
        }else if(position == 'prepend'){
          $(parent).prepend($(tempParent).children());
        }else if(position == 'html'){
          if($(parent).prop('nodeName') == 'TABLE'){
            $(parent).find('tbody').html($(tempParent).children());
          }else{
            $(parent).html($(tempParent).children());
          }
        }
        $(tempParent).remove();
      }
    };

    methods.renderBind = function(ele, dlist){
      let that = $(ele);
      let bname = that.attr('jdBind');
      let bnamearrmax = bname.split('||');
      let reg = /^\{(.*)\}(\w*)/;
      for(let i=0; i<bnamearrmax.length; i++){
        let bnamearr = bnamearrmax[i].split('::');
        let bname1 = bnamearr[0] || 'text';
        let bname2 = bnamearr[1];
        let bname2_pre = '';
        if(reg.test(bname2)){
          let match = bname2.match(reg);
          if(match[0] && match[1] && match[2]){
            bname2_pre = match[1];
            bname2 = match[2];
          }
        }
        let regStyle = /^(Style)([\w-]*)/;
        let regRemoveStyle = /^(RemoveStyle)([\w-]*)/;
        if(dlist){
          let bname2_last = bname2_pre + dlist[bname2];
          if(bname1 == 'text'){
            that.text(bname2_last);
          }else if(bname1 == 'html'){
            that.html(bname2_last);
          }else if(bname1 == 'value'){
            that.val(bname2_last);
          }else if(bname1 == 'checked'){
            if(dlist[bname2] == true){
              that.prop('checked', true);
            }else{
              that.prop('checked', false);
            }
          }else if(bname1 == 'addClass'){
            if(typeof(dlist[bname2]) == 'undefined'){
              bname2_last = bname2_pre + bname2;
            }
            that.addClass(bname2_last);
          }else if(bname1 == 'removeClass'){
            if(typeof(dlist[bname2]) == 'undefined'){
              bname2_last = bname2_pre + bname2;
            }
            that.removeClass(bname2_last);
          }else if(bname1 == 'setClass'){
            if(typeof(dlist[bname2]) == 'undefined'){
              bname2_last = bname2_pre + bname2;
            }
            that.attr('class', bname2_last);
          }else if(regStyle.test(bname1)){  //修改style样式
            let match = bname1.match(regStyle);
            if(match && match[2]){
              let cname = match[2].toLowerCase();
              if(cname == 'background' || cname == 'background-image'){
                that.css('background-image', 'url("' + bname2_last + '")');
              }else{
                that.css(cname, bname2_last);
              }
            }
          }else if(regRemoveStyle.test(bname1)){  //移除style样式
            let match = bname1.match(regRemoveStyle);
            if(match && match[2]){
              let cname = match[2].toLowerCase();
              that.css(cname, '');
            }
          }else{
            that.attr(bname1, bname2_last);
          }
        }
      }
      that.attr('jdBind', null);
    };

    //数值动态增长
    methods.dataInc = function(ele, data, times){
      ele.attr('jdDataInc', null);
      if(ele.hasClass(options.active)){
        return false;
      }
      let speed = 51;  //速度
      if(data < 100){  //数值过小的速度设置慢些
        speed = 150;
      }
      if(!times){
        times = 2000;  //默认动画时间
      }
      let tnum = times / speed;  //执行次数
      let range = data / tnum;  //每次幅度
      if(range < 1){
        range = 1;
      }
      let newval = 0;

      let timer = setInterval(function(){
        newval += range;
        newval = parseInt(newval);
        if(newval > data){
          newval = data;
          ele.html(newval);
          clearInterval(timer);
          return false;
        }
        ele.html(newval);
      }, speed);
      ele.addClass(options.active);
    };

    //元素容器
    methods.ref = {};

    //选项卡
    methods.tabs = function(o, ele){
      let index = $(o).index();
      let children = $(ele).children();
      $(o).addClass(options.active).siblings().removeClass(options.active);
      $(children[index]).addClass(options.active).show().siblings().removeClass(options.active).hide();
    };

    //右键菜单
    methods.contextmenu = function(ele, menulist, style){
      let thatmax = this;
      menulist = menulist || null;

      if($(ele).length > 0 && menulist.length > 0){
        $(ele).each(function(){
          let that = $(this);
          that.contextmenu(function(e){
            e.preventDefault();  //阻止右键菜单默认
            thatmax.contextmenuClose();

            //风格
            style = style || '';
            let style_bg, style_bor;
            if(style == 'natural'){  //自然
              style_bg = '#cef5cf';
              style_bor = '#49bb4c';
              style_color = '#222222'
            }else if(style == 'dark'){  //暗色
              style_bg = '#535353';
              style_bor = '#222222';
              style_color = '#ffffff';
            }else{  //默认清新风格
              style_bg = '#c7eaee';
              style_bor = '#0088cc';
              style_color = '#222222';
            }

            let ptop = e.pageY;
            let pleft = e.pageX;
            let textmenu = $('<div class="jd-contextmenu" style="background-color:#fff; position:absolute; z-index:99999; top:' + ptop + 'px; left:' + pleft + 'px;"><div style="background-color:#fff; position:relative; z-index:2; border:1px solid #ccc; display:inline-block; min-width:150px;"></div></div>').appendTo('body');
            let textmenu_ul = $('<ul style="margin:2px; display:block; padding:0; position:relative; z-index:2;"></ul>').appendTo(textmenu.find('div'));
            let menuli;
            for(let i=0; i<menulist.length; i++){
              menuli = $('<li ' + (menulist[i]['disabled'] === true ? 'data-disabled="1"' : '') + 'style="list-style:none; cursor:pointer; color:' + (menulist[i]['disabled'] === true ? '#b3b3b3' : '#222222') + '; font-size:14px; padding:0 10px; height:30px; line-height:30px; background-color:#ffffff; box-sizing:border-box; border:1px solid #ffffff; white-space:nowrap;">' + menulist[i]['menu'] + '</li>').appendTo(textmenu_ul);
              menuli.hover(function(){
                $(this).css({
                  'background-color': style_bg,
                  'border': '1px solid ' + style_bor,
                  'color': (menulist[i]['disabled'] === true ? '#b3b3b3' : style_color)
                });
              }, function(){
                $(this).css({
                  'background-color': '#ffffff',
                  'border': '1px solid #ffffff',
                  'color': (menulist[i]['disabled'] === true ? '#b3b3b3' : '#222222')
                });
              });
              if(typeof(menulist[i]['call']) == 'function' && (!menulist[i]['disabled'] || menulist[i]['disabled'] == false)){
                let call = menulist[i]['call'];
                menuli.click(function(){
                  call();
                  thatmax.contextmenuClose();
                });
              }
            }

            //元素在网页右侧
            let menuwidth = textmenu.width();
            let ifright = pleft + menuwidth + 20;  //加20误差
            if(ifright > thatmax.xwidth){
              pleft = pleft - menuwidth;
              textmenu.css('left', pleft + 'px');
            }

            //元素在网页底部
            let menuheight = textmenu.height();
            let ifbottom = e.clientY + menuheight + 10;  //加10误差
            if(ifbottom > thatmax.xheight){
              ptop = ptop - menuheight;
              textmenu.css('top', ptop + 'px');
            }

            textmenu.append('<div style="width:100%; height:100%; position:absolute; top:3px; left:3px; z-index:1; background-color:rgba(0, 0, 0, 0.2);">');
          });
        });
      }
    };

    //关闭右键菜单
    methods.contextmenuClose = function(){
      $('.jd-contextmenu').remove();
    };

    //////////////////////////////////

    //点击其他区域关闭右键菜单
    $(document).on('click', function(e){
      let plen = $(e.target).closest('.jd-contextmenu').length;
      if(plen == 0 || (plen == 1 && $(e.target).data('disabled') != 1)){
        methods.contextmenuClose();
      }
    });

    //下拉导航的显示和隐藏
    const jdNavSelect = $('[jdNavSelect]');
    if(jdNavSelect.length > 0){
      jdNavSelect.each(function(){
        let that = $(this);
        let cssname = that.attr('jdNavSelect');
        let fade = that.attr('jdNavSelectFade') || 0;
        fade = Number(fade);
        let li = that.find('dd');
        li.each(function(){
          let that = $(this);
          let index = $(this).index();
          index = index == 0 ? 'first' : index;
          that.on('mouseenter', function(){
            that.parent().parent().addClass(options.active + '_' + index);
          });
          that.on('mouseleave', function(){
            that.parent().parent().removeClass(options.active + '_' + index);
          });
        });
        that.on('mouseenter', function(){
          that.find('.' + cssname).fadeToggle(fade);
        });
        that.on('mouseleave', function(){
          that.find('.' + cssname).fadeToggle(fade);
        });
        that.attr('jdNavSelect', null);
      });
    }

    //鼠标经过添加css
    const jdHover = $('[jdHover], [jdHoverOn], [jdHoverSon], [jdHoverSonOn]');
    if(jdHover.length > 0){
      jdHover.each(function(){
        let that = $(this);
        let leave = false;
        let act;
        if(that.attr('jdHover')){
          leave = true;
          act = 'jdHover';
        }else if(that.attr('jdHoverOn')){
          leave = false;
          act = 'jdHoverOn';
        }else if(that.attr('jdHoverSon')){
          leave = true;
          act = 'jdHoverSon';
        }else if(that.attr('jdHoverSonOn')){
          leave = false;
          act = 'jdHoverSonOn';
        }else{
          return false;
        }

        let jd_arr = that.attr(act).split('||');
        let ele = jd_arr[0];
        let cssname = jd_arr[1] || options.active;
        if(act == 'jdHover' || act == 'jdHoverOn'){  //给自身添加
          let actele = (ele == 'this' || ele == 'siblings') ? that : $(ele);
          that.on('mouseenter', function(){
            if(ele == 'siblings'){
              actele.addClass(cssname).siblings().removeClass(cssname);
            }else{
              actele.addClass(cssname);
            }
          });

          if(leave === true){  //是否鼠标移出
            that.on('mouseleave', function(){
              actele.removeClass(cssname);
            });
          }
        }else if(act == 'jdHoverSon' || act == 'jdHoverSonOn'){  //给子元素添加
          let son = that.find(ele);
          if(son.length > 0){
            son.each(function(){
              let thatson = $(this);
              thatson.on('mouseenter', function(){
                if(act == 'jdHoverSon'){
                  thatson.addClass(cssname).siblings().removeClass(cssname);
                }else{
                  thatson.addClass(cssname);
                }
              });
            });
          }
        }

        that.attr('jdHover', null);
        that.attr('jdHoverOn', null);
        that.attr('jdHoverSon', null);
        that.attr('jdHoverSonOn', null);
      });
    }

    //元素滚动到顶部事件
    const jdPoiup = $('[jdPoiup]');
    if(jdPoiup.length > 0){
      let array = new Array();
      jdPoiup.each(function(){
        let that = $(this);
        let height = that.attr('jdPoiHeight') || that.height();
        let poi = that.attr('jdPoiup') || 0;
        let reg = /^[.|#]+\w+/;
        let poihei = 0;
        if(reg.test(poi)){
          let poiarr = poi.split(',');
          for(let i=0; i<poiarr.length; i++){
            let ele = poiarr[i].replace(/^\s*|\s*$/g, '');
            poihei += $(ele).height();
          }
          poi = poihei;
        }
        let blank = that.attr('jdPoiBlank') || '1';
        let css_before = 'width:100%; height:0; overflow:hidden;';
        let css_after = 'width:100%; height:' + height + 'px; overflow:hidden; position:relative; z-index:-10; display:none;';
        let before = $('<div style="' + css_before + '"></div>').insertBefore(that);
        let after = '';
        if(blank == '1'){
          after = $('<div style="' + css_after + '"></div>').insertAfter(that);
        }
        let arr = {'before': before, 'self': that, 'after': after, 'poi': poi, 'poihei': poihei};
        that.attr('jdPoiup', null);
        that.attr('jdPoiBlank', null);
        array.push(arr);
      });

      if(array.length > 0){
        let scrtop, poitop;
        $(window).scroll(function(){
          scrtop = $(this).scrollTop();
          for(let i=0; i<array.length; i++){
            poitop = array[i]['before'].offset().top;
            if(scrtop >= (poitop - array[i]['poi'])){
              array[i]['self'].addClass(options.active);
              if(array[i]['poihei'] > 0){
                array[i]['self'].css('top', array[i]['poihei']);
              }
              if(array[i]['after']){
                array[i]['after'].show();
              }
            }else{
              array[i]['self'].removeClass(options.active);
              if(array[i]['poihei'] > 0){
                array[i]['self'].css('top', '');
              }
              if(array[i]['after']){
                array[i]['after'].hide();
              }
            }
          }
        });
      }
    }

    return methods;
  }
})(jQuery);